package destiny;

import java.text.DateFormat;
import java.util.Date;

import lunisolar.LunarDate;
import lunisolar.农历;
import destiny.时.节令;
import destiny.预测.Consts;
import destiny.预测.干支数;
import destiny.预测.流年行运排盘;
import destiny.预测.预测论断;

public class 四柱预测 {
	private Date birthday;
	private boolean genderIsMan;

	private 干支 年柱, 月柱, 日柱, 时柱;

	public 干支 年柱() {
		return 年柱;
	}

	public 干支 月柱() {
		return 月柱;
	}

	public 干支 日柱() {
		return 日柱;
	}

	public 干支 时柱() {
		return 时柱;
	}

	public boolean 乾造() {
		return genderIsMan;
	}

	private 预测论断 predict;

	@SuppressWarnings("deprecation")
	public 四柱预测(Date solarDateTime, boolean genderIsMan) throws Exception {
		if (solarDateTime.getYear() <= 1900 - 1900
				|| solarDateTime.getYear() > 2100 - 1900)
			throw new Exception("year 1901-2100 only");
		this.birthday = solarDateTime;

		initialize(四柱.年柱(solarDateTime), 四柱.月柱(solarDateTime),
				四柱.日柱(solarDateTime), 四柱.时柱(solarDateTime), genderIsMan);
	}

	private void initialize(干支 年柱, 干支 月柱, 干支 日柱, 干支 时柱, boolean genderIsMan) {
		this.年柱 = 年柱;
		this.月柱 = 月柱;
		this.日柱 = 日柱;
		this.时柱 = 时柱;

		this.genderIsMan = genderIsMan;

		predict = new 预测论断(new 干支[] { 年柱, 月柱, 日柱, 时柱 }, genderIsMan);
	}

	public void 综合命评() {
		predict.综合命评();
	}

	public void 流年行运() throws Exception {
		System.out.println("== 流年行运 ==");
		System.out.println("\t所谓命运，只知以表象而论，如果内心平静，万事看开，又如何？");
		System.out.println("\t由于古今天象变迁，前后可能相差半年至一年。");
		System.out.println("\t特殊名词：宫名（如果已经不在或者尚未遇到，则不论）");
		流年行运(命运.起运交脱(birthday, genderIsMan), 命运.大运(birthday, genderIsMan));
	}

	@SuppressWarnings("deprecation")
	private void 流年行运(Date 运, 干支[] 大运) throws Exception {
		干支数[] gzs = null;

		LunarDate ld = 农历.TimeToLunar(运);
		Date d1, d2 = 运, d3, now = new Date();
		for (int i = 0; i < 大运.length; ++i) {

			int jn = 0;
			d1 = d2;
			d2 = new Date(d2.getYear(), 0, (int) 节令.term(d2.getYear() + 1900,
					3, true));
			if (d2.getTime() > d1.getTime()) {
				gzs = 流年行运命评(gzs, 大运[i], d1, d2, jn);
				d1 = d2;
			}
			ld.setYear(ld.getYear() + 1);
			for (int j = 0; j < 9; ++j) {
				if (d1.getYear() > now.getYear())
					return;
				d2 = new Date(d2.getYear() + 1, 0, (int) 节令.term(
						d2.getYear() + 1 + 1900, 3, true));
				gzs = 流年行运命评(gzs, 大运[i], d1, d2, jn);
				++jn;
				d1 = d2;
				ld.setYear(ld.getYear() + 1);
			}
			d3 = new Date(d2.getYear() + 1, 0, (int) 节令.term(
					d2.getYear() + 1 + 1900, 3, true));
			d2 = 农历.LunarToTime(ld);
			if (d2.getTime() > d3.getTime()) {
				gzs = 流年行运命评(gzs, 大运[i], d1, d3, jn);
				d1 = d3;
			}
			gzs = 流年行运命评(gzs, 大运[i], d1, d2, jn);
		}
	}

	private 干支数[] 流年行运命评(干支数[] gzsOld, 干支 运, Date 始, Date 终, int 大运经年)
			throws Exception {
		/**
		 * 0 - 运柱; 1 - 流年柱
		 */
		干支[] 流年行运 = { 运, 四柱.年柱(始) };

		干支数[] gzs = predict.流年行运(流年行运, 大运经年);

		if (gzsOld == null)
			return gzs;

		StringBuilder sb = new StringBuilder();
		for (int i = Consts.流年行运月序; i <= Consts.流年行运时序; ++i) {
			String s;
			if (i == Consts.流年行运日序) {
				s = "命主";
			} else {
				s = 流年行运排盘.宫名2(i, true, genderIsMan);
			}
			String mp = predict.流年行运宫评(gzsOld, gzs, i, true, s);
			if (mp.length() > 0) {
				sb.append(String.format("\t%s\n", mp));
			}
			s = 流年行运排盘.宫名2(i, false, genderIsMan);
			mp = predict.流年行运宫评(gzsOld, gzs, i, false, s);
			if (mp.length() > 0) {
				sb.append(String.format("\t%s\n", mp));
			}
		}

		sb.append(星命(gzsOld, gzs, Consts.流年行运运序));
		sb.append(星命(gzsOld, gzs, Consts.流年行运流年序));

		if (sb.length() > 0) {
			System.out.println("---------------------------------------");
			System.out.println(String.format("\t%s - %s (%s %s)", DateFormat
					.getDateInstance().format(始), DateFormat.getDateInstance()
					.format(终), 流年行运[0], 流年行运[1]));
			System.out.println(sb.toString());
		}
		return gzs;
	}

	private String 星命(干支数[] gzsOld, 干支数[] gzs, int index) {
		StringBuilder sb = new StringBuilder();
		String mp = predict.流年行运星评(gzs, index, false);
		if (mp.length() > 0) {
			sb.append(String.format("\t%s\n", mp));
		}

		mp = predict.流年行运星评(gzs, index, true);
		if (mp.length() > 0) {
			sb.append(String.format("\t%s\n", mp));
		}
		return sb.toString();
	}
}
